var bleUtils = require('ble-utils.js');
const PrinterJobs = require('printer/printerjobs')
const BLELockerUtil = require('../utils/BLELocker.js')
const util = require('../utils/util.js')
const app = getApp();

const hprtName = 'N41BT-0DA6';
const LAST_HPRT_CONNECTED_DEVICE = 'last_hprt_connected_device';
var _Device = null;
var printContent = null;
var printCounts = 1;
var lineAddrCount = 0;
var lineGoodsCount = 0;
/**
 * 直接打印
 */
function print(content,counts,lineAddrCount,lineGoodsCount) {
  _Device = null;   
  printContent = content;
  printCounts = counts;
  lineAddrCount = lineAddrCount;
  lineGoodsCount = lineGoodsCount;
  let device = wx.getStorageSync(LAST_HPRT_CONNECTED_DEVICE);
  if(device) {
      //之前连接过
      console.log("之前连接过直接连接打印")
    bleUtils.openBluetoothAdapter({}).then(function (res) {//初始化蓝牙模块儿
      return bleUtils.getBluetoothAdapterState({})//获取适配器状态
    }).then(function(){
      connectPrint(device)
    });
  }else {
     //搜索设备 
     console.log("未连接过进行打印")
     firstCon(); 
  }  

}

function firstCon(){

  bleUtils.openBluetoothAdapter({}).then(function (res) {//初始化蓝牙模块儿
    return bleUtils.getBluetoothAdapterState({})//获取适配器状态
  }).then(function (res) {
    if (res.available) {//蓝牙可用
      bleUtils.startBluetoothDevicesDiscovery({
        // services: ["FEE7"],//过滤，只搜索微信硬件设备
        allowDuplicatesKey: true,
        interval: 0.1
      }).then(function (res) {
        console.log("开始扫描设备...." + hprtName, res);
        bleCallback(hprtName)
      })
    }
  },function(){
    bleUtils.closeBluetoothAdapter({});   
  })

}

function bleCallback(mac) {
  bleUtils.onBluetoothAdapterStateChange(function (res) {//蓝牙转态回调
    if (res.available) {
      console.log("蓝牙适配器可用");     
    } else {
      console.log("蓝牙适配器不可用");
      wx.showModal({
        title: '提示',
        content: '请打开蓝牙',
      })
    }
  }),
    bleUtils.onBLEConnectionStateChange(function (res) {//链接状态回调
      console.log("连接状态" + res.connected,res);     
    })
  bleUtils.onBluetoothDeviceFound(function (res) {
    //搜索到的蓝牙设备回调，对应可以将相关信息显示在界面上
    var devices = res.devices;
    for (var i = 0; i < devices.length; i++) {
      if (_Device != null) {
        continue;
      }
      var dev = findConDev(devices[i], mac);
      var dName = devices[i].localName ? devices[i].localName : devices[i].name;
      console.log("搜索到的设备:" + dName, devices[i], dev, _Device);
      if (dev != null && _Device == null) {
        _Device = dev;
        console.log("匹配设备结束开始连接设备", dev);
        wx.setStorageSync(LAST_HPRT_CONNECTED_DEVICE,dev);
        connectPrint(dev);
        break;
      }
    }
  })
}


//判断搜索到的设备是否为要找的设备
function findConDev(device, mac) {
  let devName = null;
  //避免同一个设备多次重复回调
  if (device.name == null) {
    console.log('【匹配设备失败，设备的name为空】');
  } else {
    devName = device.name;
  }
  if (device.localName == null) {
    // console.log('【匹配设备失败，设备的localName为空】');//todo log
  } else {
    devName = device.localName;
  }

  //蓝牙广播数据
  if (devName == mac) {
    console.log("【搜索到蓝牙设备】匹配到设备------》", device,  mac)
    return device;
  }

  return null;
}

function connectPrint(device) {
   if(!device) {
     console.error("设备不存在，无法进行连接")
     return;
   }
  console.log("开始连接打印",device);
  bleUtils.createBLEConnection({
    deviceId: device.deviceId,
    timeOut: 5000
  },function(err){
     console.log("连接失败",err)
  }).then(function(){
    //设备链接成功后记得停止扫描
    bleUtils.stopBluetoothDevicesDiscovery({})
    return bleUtils.getBLEDeviceServices({//获取设备对应的服务
      deviceId: device.deviceId
    })
  }).then(function(res){
    console.log("设备的服务信息", res);
    for (let i = 2; i < res.services.length; i++) {
      if (res.services[i].isPrimary) {
        var uuid = res.services[i]["uuid"]
        console.log("服务uuid-->", uuid);
        device.fee7 = res.services[i] ;
      }
    }  
    console.log("服务--->uuid", device.fee7["uuid"]);
    return bleUtils.getBLEDeviceCharacteristics({//获取特征值
      deviceId: device.deviceId,
      serviceId: device.fee7["uuid"]
    })
    }).then(function (res) {
      console.log("设备特征码", res);
      
      for (let i = 0; i < res.characteristics.length; i++) {
        const item = res.characteristics[i]
        if (item.properties.write) {
          device.fec7 = item
          console.log('item.uuid=', item.uuid);
          break;
        }
      }

      console.log("调用打印函数------》", printCounts);
      
        
      startPrintData(device);

    })
}

  function startPrintData(device){
    console.log("开始打印,下一页的数据", app.globalData.printNextPageStr)
    let printerJobs = new PrinterJobs();

    // console.log('ArrayBuffer', 'length: ' + buffer.byteLength, ' hex: ' + BLELockerUtil.ab2hex(buffer));
    // 1.并行调用多次会存在写失败的可能性
    // 2.建议每次写入不超过20字节
    // 分包处理，延时调用
    const maxChunk = 20;
    const delay = 50;

    var t = '';
    t = t + 'SIZE 75 mm,130 mm\r\n';
    t = t + 'SET COUNTER @1 1\r\n';
    t = t + '@1="001"\r\n';
    t = t + 'CLS\r\n';
    let printDate = util.formatTime(new Date());
    t = t + 'TEXT 20,40,"0",0,2,2,"第"\r\n';
    t = t + 'TEXT 70,40,"0",0,2,2,@1\r\n';
    t = t + 'TEXT 140,40,"0",0,2,2,"份 共' + printCounts + '份"\r\n';
    t = t + 'TEXT 730,50,"0",0,1,1," [' + printDate + ']"\r\n';

    t = t + printContent;

    t = t + 'PRINT ' + printCounts + ',1'
    console.log("进行编码")
    printerJobs
      .println(t)

    console.log("转换成buffer")
    let buffer = printerJobs.buffer();

    console.log("开始发送", device)
    for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
      let endLen = i + maxChunk;
      let subPackage = buffer.slice(i, endLen <= length ? (endLen) : length);
      setTimeout(function () {
        writeBLECharacteristicValue(subPackage, device, endLen >= length);
      }, j * delay);
    }
  }

  function writeBLECharacteristicValue(buffer,device,isOver) {
    wx.writeBLECharacteristicValue({
      deviceId: device.deviceId,
      serviceId: device.fee7["uuid"],
      characteristicId: device.fec7.uuid,
      value: buffer,
      success(res) {
        console.log('writeBLECharacteristicValue success', res)
        if(isOver) {
          console.log("打印完毕", app.globalData.printNextPageStr);
          if (app.globalData.printNextPageStr) {
            console.log("接着打印剩余的部分");
            printContent = app.globalData.printNextPageStr;
            app.globalData.printNextPageStr = "";
            setTimeout(function(){
              startPrintData(device);            
            },1000);            
          }else {
            console.log("打印完成关闭蓝牙连接", device);
            setTimeout(function () {
              closeCon(device);
            }, 1500);
          }                    
        }
      },
      fail(res) {
        console.log('writeBLECharacteristicValue fail', res)
      }
    })
  }


function closeCon(device) {
  bleUtils.closeBLEConnection({
    deviceId: device.deviceId
  }).then(function (res) {
    bleUtils.closeBluetoothAdapter({});   
  },function(){
    bleUtils.closeBluetoothAdapter({});
  })
}

function txtHandle(txt, lineHeight, y, startX = 10,firstLineLen =16,secondLineLen = 14,xM =2,yM =2,font = "1"){
  let str = "";
  let lineCounts = 0;
  if (txt.length <= firstLineLen) {
    str += 'TEXT ' + startX + ',' + y + ',"' + font +'",0,' + xM +',' + yM +',"' + txt + '"\r\n';
    y += lineHeight;
    lineCounts++;
  } else {
    let start = 0;
    let end = firstLineLen;
    str += 'TEXT ' + startX + ',' + y + ',"' + font+'",0,' + xM + ','+ yM +',"' + txt.substring(start, end) + '"\r\n';
    y += lineHeight;
    start = end;
    let lineLen = secondLineLen;
    let count = Math.ceil(txt.length / lineLen);
    lineCounts = lineCounts + count;
    for (var i = 0; i < count; i++) {
      end = start + lineLen;
      if (end > txt.length) {
        end = txt.length;
      }
      let tmp = txt.substring(start, end);
      if (tmp == "") {
        break;
      }
      str += 'TEXT 60,' + y + ',"' + font +'",0,'+ xM +',' + yM +',"' + txt.substring(start, end) + '"\r\n';
      y += lineHeight;
      start = end;
    }
  }
  return { "str": str, "y": y, "lineCounts": lineCounts};
}



module.exports ={
   print: print,
   txtHandle: txtHandle
}